package com.time.tell.the.truth.netty.server;

import com.time.tell.the.truth.netty.dto.User;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.List;

@Slf4j
public class ParseCmdHandler extends ByteToMessageDecoder {

  @Override
  protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {

    if (!hasAtLeastOneCompleteObj(in)) {
      return;
    }

    // 跳过totalLength对应的4个字节
    in.readInt();

    int nameLength = in.readInt();
    String name = in.readCharSequence(nameLength, StandardCharsets.UTF_8).toString();
    int age = in.readInt();
    User user = User.builder().name(name).age(age).build();
    out.add(user);
    log.info("parse user success {}", user);
  }

  // 解决粘包/分包问题
  private boolean hasAtLeastOneCompleteObj(ByteBuf in) {
    if (in.readableBytes() < 4) {
      return false;
    }

    int totalLength = in.getInt(0);
    if (in.readableBytes() < totalLength) {
      return false;
    }
    return true;
  }

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    log.error("exceptionCaught", cause);
  }
}
